---@class GT.abilityInit 技能物编获得初始化系统
---@field akData table<AbilityKey,abilityInit_data>  技能初始化数据
---@field kv kv_class[] 自定义键值
GT.abilityInit = class()

---@type table<AbilityKey,abilityInit_data>  初始化的技能数据
abilityInit = OrderedTable()

---@alias text fun(k:AbilityKey,u:GT.unit,a:GT.ability):string 

---@class abilityInit_data 技能获得初始化参数列表
---@field ak AbilityKey 技能编号
---@field obtain {text:string,call:ABILITY_OBTAIN}[] 技能获得回调
---@field lose {text:string,call:ABILITY_LOSE}[]  技能失去回调
---@field ability_sp {text:string,call:ABILITY_SP_END}[] 施法出手回调
---@field ability_cst {text:string,call:ABILITY_CST_END}[] 施法完成回调
---@field ability_end {text:string,call:ABILITY_BS_END}[] 施法停止回调
---@field attr table<uKeyAttr,number> 单位属性
---@field kv table<any,any> 自定义键值
---@field playerKv table<string,number> 玩家属性消耗
---@field skills_event table<string,number> 玩家属性消耗
---@field all_dag_event {text:text,call:UNIT_HURT_OTHER_COMPLETE}[] 造成伤害(结算完成)-任意单位
---@field attr_ability table<ABILITY_FLOAT_ATTRS_KEY,number> 技能属性
---@field build_unit_ID UnitKey 绑定建筑ID



---@param data abilityInit_data[]
function GT.abilityInit:ctor(data)
    for k, v in pairs(data) do
        abilityInit[v.ak] = v
    end
end

---@param ikData abilityInit_data[]
---@return GT.abilityInit
function GT.abilityInit.obj(ikData)
    return new(GT.abilityInit, ikData)
end

---技能事件描述
---@param key AbilityKey
---@param u GT.unit
---@param a GT.ability
---@return string
function GT.abilityInit.event_tip(key,u,a)
    local d = abilityInit[key]
    local txt = StringBuilder.new()
    if d ~= nil then
        
        if d.attr_ability~=nil then
            for k, v in pairs(d.attr_ability) do
                txt:append_line(GT.color['亮绿'](k..'='..v))
            end
            txt:append_line("")
        end
        if d.obtain ~= nil then
            for i, v in ipairs(d.obtain) do
                if v.text ~= nil then
                    txt:append_line('获得-->' .. v.text)
                end
            end
        end
        if d.lose ~= nil then
            for i, v in ipairs(d.lose) do
                if v.text ~= nil then
                    txt:append_line(GT.color['金']('失去-->'..v.text))
                end
            end
        end

        if d.ability_sp ~= nil then
            for i, v in ipairs(d.ability_sp) do
                if v.text ~= nil then
                    txt:append_line(GT.color['金']('施法出手-->'..v.text))
                    
                end
            end
        end

        if d.ability_cst ~= nil then
            for i, v in ipairs(d.ability_cst) do
                if v.text ~= nil then
                    txt:append_line(GT.color['金']('施法完成-->'..v.text))
                    
                end
            end
        end

        if d.ability_end ~= nil then
            for i, v in ipairs(d.ability_end) do
                if v.text ~= nil then
                    txt:append_line(GT.color['金']('施法停止-->'..v.text))

                end
            end
        end
        if d.all_dag_event ~= nil then
            for i, v in ipairs(d.all_dag_event) do
                if v.text ~= nil then
                    txt:append_line('造成伤害-->'..v.text(key,u,a))

                end
            end
        end
    end
    return txt:tostring(false)
end

---获得技能
GT.event.ABILITY_OBTAIN(function(u, a)
    local d = abilityInit[a:get_AbilityKey()]
    if d ~= nil then
        ---将初始化技能属性数据添加到单位中
        u.ability_data[a:__tostring()]=GT.copy_table(d)
        ---初始化属性
        if d.attr ~= nil then
            u:diy_add_attr(d.attr)
            for k, v in pairs(d.attr) do
                a.attr[k] = v
            end
        end
        ---设置自定义键值
        if d.kv ~= nil then
            for key, value in pairs(d.kv) do
                a[key]=value
            end
            -- for k, v in pairs(d.kv) do
            --     a:set(v.K, v.V, v.call)
            -- end
        end

        if d.obtain ~= nil then
            for i, v in ipairs(d.obtain) do
                v.call(u, a)
            end
        end


        if d.playerKv ~= nil then
            for key, value in pairs(d.playerKv) do
                ---设置玩家属性消耗
                a:api_set_ability_player_attr_cost(key, value)
            end
        end

        if d.all_dag_event ~= nil then
            for i, v in ipairs(d.all_dag_event) do
                u:diy_add_all_dag_event_ability(a:get_AbilityKey(), v.call)
            end
        end
        if d.attr_ability~=nil then
            for k, v in pairs(d.attr_ability) do
                a.binding[k]=v
            end
        end
    end
end)
--失去技能
GT.event.ABILITY_LOSE(function(u, a)
    local d = abilityInit[a:get_AbilityKey()]
    if d ~= nil then
        ---将初始化技能属性数据添加到单位中
        u.ability_data[a:__tostring()]=nil
        if d.lose ~= nil then
            for i, v in ipairs(d.lose) do
                v.call(u, a)
            end
        end

        if d.attr ~= nil then
            u:diy_del_attr(d.attr)
        end
        u:diy_del_all_dag_event_ability(a:get_AbilityKey())
    end
end)
---施法出手
GT.event.ABILITY_SP_END(function(a, u, tu, td, ti, tp)
    local d = abilityInit[a:get_AbilityKey()]
    if d ~= nil then
        if d.ability_sp ~= nil then
            for i, v in ipairs(d.ability_sp) do
                v.call(a, u, tu, td, ti, tp)
            end
        end
    end
end)
--施法完成
GT.event.ABILITY_CST_END(function(a, u, tu, td, ti, tp)
    local d = abilityInit[a:get_AbilityKey()]
    if d ~= nil then
        if d.ability_cst ~= nil then
            for i, v in ipairs(d.ability_cst) do
                v.call(a, u, tu, td, ti, tp)
            end
        end
    end
end)
--施法停止
GT.event.ABILITY_END(function(a, u, tu, td, ti, tp)
    local d = abilityInit[a:get_AbilityKey()]
    if d ~= nil then
        if d.ability_end ~= nil then
            for i, v in ipairs(d.ability_end) do
                v.call(a, u, tu, td, ti, tp)
            end
        end
    end
end)

--造成伤害
GT.event.UNIT_HURT_OTHER_COMPLETE(function(su, tu, d, d_type, is_crit, is_attack, ability)
    if su==nil then
        return
    end
    local e = su:diy_get_all_dag_event_ability()
    if e~=nil then
        for k, v in pairs(e) do
            for i, value in ipairs(v) do
                value(su, tu, d, d_type, is_crit, is_attack, ability)
            end
        end
    end
    
end)
